package com.ldk.admin.controller;

import java.io.IOException;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Cookie;

import com.ldk.admin.constants.CONFIG;
import com.ldk.framework.entity.AdminLog;
import com.ldk.framework.entity.CountBean;
import com.ldk.framework.service.IAdminLogService;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.ldk.admin.common.ResponseResult;
import com.ldk.admin.constants.FORM;
import com.ldk.admin.constants.SESSION;
import com.ldk.admin.factory.MenuExt;
import com.ldk.admin.factory.MenuFactory;
import com.ldk.base.framework.util.ConvertUtil;
import com.ldk.base.framework.util.EncryptUtil;
import com.ldk.base.framework.util.SystemUtil;
import com.ldk.base.framework.util.VerifyCodeUtil;
import com.ldk.framework.entity.AdminUser;
import com.ldk.framework.entity.Menu;
import com.ldk.framework.service.IAdminUserService;
import com.ldk.framework.service.IDriverService;
import com.ldk.framework.service.IMenuService;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;

import com.sun.management.OperatingSystemMXBean;

import performance.IMonitorService;
import performance.MonitorInfoBean;
import performance.MonitorServiceImpl;

@Controller
@RequestMapping("/")
public class HomeController extends BaseController {

    @Autowired
    private IMenuService menuService;
    @Autowired
    private IAdminUserService adminUserService;
    @Autowired
    private IAdminLogService adminLogService;
    @Autowired
    private IDriverService driverService;


    @RequestMapping("/")
    public ModelAndView login(ModelMap map, HttpServletRequest request) {
        //Cookie自动登录
        String userName = "";
        String password = "";
        Cookie[] cookies = request.getCookies();
        if (cookies != null && cookies.length > 0) {
            for (Cookie c : cookies) {
                if (c.getName().equals("userName")) {
                    userName = c.getValue();
                }
                if (c.getName().equals("password")) {
                    password = c.getValue();
                }
            }
        }
        if (!StringUtils.isBlank(userName) && !StringUtils.isBlank(password)) {
            AdminUser query = new AdminUser();
            query.setUserName(userName);
            AdminUser tmp = adminUserService.selectOne("", query);
            if (tmp != null) {
                String salt = tmp.getSalt();
                String textPwd = String.format("%s%s", password, salt);
                String md5Pwd = EncryptUtil.md5(textPwd);

                query.setPassword(md5Pwd);
                query.setEnabled(true);

                AdminUser admin = adminUserService.selectOne("", query);
                if (admin != null) {
                    //重新获取根据用户ID
                    query = new AdminUser();
                    query.setUserId(admin.getUserId());
                    AdminUser user = adminUserService.selectByKey("", query);
                    //这些敏感信息不存放在SESSION中
                    user.setSalt("");
                    user.setPassword("");

                    request.getSession().setAttribute(SESSION.USER, user);

                    return new ModelAndView("redirect:/home");
                }
            }
        }

        setForm(map, "/login", null);
        return new ModelAndView("login");
    }

    @RequestMapping(value = "/login", method = {RequestMethod.POST})
    public ModelAndView login(@RequestParam(value = "userName", required = true, defaultValue = "") String userName,
                              @RequestParam(value = "password", required = true, defaultValue = "") String password,
                              @RequestParam(value = "validCode", required = true, defaultValue = "") String validCode,
                              RedirectAttributes redAttr,
                              HttpServletRequest request, HttpServletResponse response) {
        ResponseResult rst = new ResponseResult();
        redAttr.addFlashAttribute(FORM.FROM_RESULT, rst);
        if (StringUtils.isBlank(userName) ||
                StringUtils.isBlank(password)) {
            rst.AddError("用户名或密码不能为空");
            return new ModelAndView("redirect:/");
        }
        if (StringUtils.isBlank(validCode)) {
            rst.AddError("验证码不能为空");
            return new ModelAndView("redirect:/");
        }
        String sessionValidCode = ConvertUtil.parseString(request.getSession().getAttribute("validCode"));
        if (!validCode.toLowerCase().equals(sessionValidCode)) {
            rst.AddError("请输入正确的验证码");
            return new ModelAndView("redirect:/");
        }

        AdminUser query = new AdminUser();
        query.setUserName(userName);

        //登录日志
        AdminLog adminLog = null;

        //登录用户客户端IP地址
        String host = request.getRemoteHost(); //主机名
        String ip_addr = request.getRemoteAddr(); //IP地址
        String browser = request.getHeader("User-Agent"); //浏览器类型

        //System.out.println("host="+host+",ip_addr="+ip_addr+",browser="+browser);
        //登录日志
        adminLog = new AdminLog();
        adminLog.setLogTime(SystemUtil.getAllSeconds());
        adminLog.setUserId(Long.parseLong("0"));
        adminLog.setUserName(userName);
        adminLog.setLogInfo("用户登入");
        adminLog.setIpAddress(host);
        adminLog.setIsOk(Long.parseLong("0"));

        //客户端IP地址当日失败登录次数
        AdminLog query2 = new AdminLog();
        query2.setIpAddress(host);
        query2.setIsOk(Long.parseLong("0"));

        Date curDay = new Date();
        String curDay_str = SystemUtil.getDateString(curDay, "yyyy-MM-dd");
        String curDay_start = curDay_str + " 00:00:00";
        query2.setStartTime(SystemUtil.stringToSeconds(curDay_start, "yyyy-MM-dd HH:mm:ss"));
        String curDay_end = curDay_str + " 23:59:59";
        query2.setEndTime(SystemUtil.stringToSeconds(curDay_end, "yyyy-MM-dd HH:mm:ss"));

        long loginCount = adminLogService.selectCount("", query2);
        //System.out.println("loginCount="+loginCount);
        //同一IP当日登录失败次数最多5次
        if (loginCount >= 1000) {
            rst.AddError("登录失败次数过多,已禁止用户当日登录");
            return new ModelAndView("redirect:/");
        }

        AdminUser tmp = adminUserService.selectOne("", query);
        if (tmp == null) {
            adminLogService.insert("", adminLog);
            rst.AddError("用户名不存在");
            return new ModelAndView("redirect:/");
        }
        String salt = tmp.getSalt();
        String textPwd = String.format("%s%s", password, salt);
        String md5Pwd = EncryptUtil.md5(textPwd);

        query.setPassword(md5Pwd);
        query.setEnabled(true);

        AdminUser admin = adminUserService.selectOne("", query);
        if (admin == null) {
            adminLogService.insert("", adminLog);
            rst.AddError("用户名或密码错误");
            return new ModelAndView("redirect:/");
        }

        //把用户名和密码保存在Cookie对象里面
        Cookie usernameCookie = new Cookie("userName", userName);
        Cookie passwordCookie = new Cookie("password", password);
        usernameCookie.setMaxAge(864000);
        passwordCookie.setMaxAge(864000);//设置最大生存期限为10天
        response.addCookie(usernameCookie);
        response.addCookie(passwordCookie);

        //生成新的混淆码
        salt = String.format("%06d", SystemUtil.generateRandom(999999));
        textPwd = String.format("%s%s", password, salt);
        //重新加密密码
        md5Pwd = EncryptUtil.md5(textPwd);

        AdminUser entity = new AdminUser();
        entity.setUserId(admin.getUserId());
        entity.setHost(host);
        entity.setLoginIp(ip_addr);
        entity.setBrowser(browser);
        //entity.setLoginTime(SystemUtil.getAllSeconds());
        entity.setLoginTime(adminLog.getLogTime());
        //新的salt 和新的密码
        entity.setSalt(salt);
        entity.setPassword(md5Pwd);

        //每次登陆后都修改一次salt和密码
        int row = adminUserService.updateByKey("", entity);
        if (row < 1) {
            rst.AddError("登陆失败");
            adminLogService.insert("", adminLog);
            return new ModelAndView("redirect:/");
        }
        //重新获取根据用户ID
        query = new AdminUser();
        query.setUserId(admin.getUserId());
        AdminUser user = adminUserService.selectByKey("", query);
        //这些敏感信息不存放在SESSION中
        user.setSalt("");
        user.setPassword("");

        //查询登录次数，用户初次登录，登录次数为0
        AdminLog adminLog2 = new AdminLog();
        adminLog2.setUserId(Long.parseLong(entity.getUserId().toString()));
        adminLog2.setLogInfo("用户登入");
        long login_count = adminLogService.selectCount("", adminLog2);
        System.out.println("登录次数 login_count=" + login_count);
        request.getSession().setAttribute("login_count", login_count);

        //登录日志
        adminLog.setUserId(Long.parseLong(entity.getUserId().toString()));
        adminLog.setIsOk(Long.parseLong("1"));
        adminLogService.insert("", adminLog);

        request.getSession().setAttribute(SESSION.USER, user);

        return new ModelAndView("redirect:/home");

    }

    @RequestMapping("/logout")
    public ModelAndView signout(HttpServletRequest request, HttpServletResponse response) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null && cookies.length > 0) {
            for (Cookie c : cookies) {
                if (c.getName().equals("userName") || c.getName().equals("password")) {
                    c.setMaxAge(0); //设置Cookie失效
                    response.addCookie(c); //重新保存。
                }
            }
        }

        //登录日志
        AdminLog adminLog = new AdminLog();
        adminLog.setLogTime(SystemUtil.getAllSeconds());
        adminLog.setUserId(Long.parseLong(this.getAdminId(request).toString()));
        adminLog.setUserName(this.getAdminUserName(request).toString());
        adminLog.setLogInfo("用户登出");
        adminLog.setIpAddress(request.getRemoteHost());
        adminLogService.insert("", adminLog);

        request.getSession().removeAttribute(SESSION.USER);
        return new ModelAndView("redirect:/");
    }

    @RequestMapping("/home")
    public ModelAndView home(HttpServletRequest request,
                             HttpServletResponse response) {
        //session是否过期
        this.isExpired(request, response);

        return new ModelAndView("home");
    }

    @RequestMapping("/menu")
    public ModelAndView menu(ModelMap map, HttpServletRequest request,
                             HttpServletResponse response) {
        //session是否过期
        this.isExpired(request, response);
        AdminUser admin = (AdminUser) request.getSession().getAttribute(SESSION.USER);
        if (admin != null) {
            List<Menu> menus = null;

            if ("admin".equalsIgnoreCase(admin.getUserName())) {
                menus = menuService.selectAll("");
            } else {
                int roleId = admin.getRoleId();
                menus = menuService.getUserMenus("", roleId);
            }
            MenuFactory factory = new MenuFactory();
            List<MenuExt> menusExt = factory.build(menus);
            map.addAttribute("menus", menusExt);
        }
        return new ModelAndView("menu");
    }

    /**
     * 该方法用来控制用户角色权限
     *
     * @param menuId
     * @param map
     * @param request
     * @return
     */
    @RequestMapping("/menu/{menuId}")
    public ModelAndView menuRedirect(@PathVariable(value = "menuId") int menuId,
                                     ModelMap map,
                                     HttpServletRequest request,
                                     HttpServletResponse response,
                                     RedirectAttributes redAttr) {
        //session是否过期
        this.isExpired(request, response);
        Menu query = new Menu();
        query.setMenuId(menuId);
        Menu menu = menuService.selectByKey("", query);

        String redirectUrl = "";
        if (menu != null && !StringUtils.isBlank(menu.getActionUrl())) {
            request.getSession().setAttribute(SESSION.CURRENT_MENU, menu);
            redirectUrl = menu.getActionUrl();
        } else {
            ResponseResult rst = new ResponseResult();
            redAttr.addFlashAttribute(FORM.FROM_RESULT, rst);
            redirectUrl = "/error";
        }
        return new ModelAndView("redirect:" + redirectUrl);
    }

    @RequestMapping("/top")
    public ModelAndView top(ModelMap map) {
        return new ModelAndView("top");
    }

    @RequestMapping("/footer")
    public ModelAndView footer(HttpServletRequest request, HttpServletResponse response) {
        ResponseResult rst = new ResponseResult();

        //客户端登录信息
        String host = request.getRemoteHost(); //主机名
        String ip_addr = request.getRemoteAddr(); //IP地址
        String browser = request.getHeader("User-Agent"); //浏览器类型

        //多重会话限制
        int userId = Integer.parseInt(this.getAdminId(request).toString());
        AdminUser query = new AdminUser();
        query.setUserId(userId);
        AdminUser model = adminUserService.selectByKey("", query);

        //System.out.println("model.getHost()="+model.getHost()+",host="+host);
        //System.out.println("model.getLoginIp()="+model.getLoginIp()+",ip_addr="+ip_addr);
        //System.out.println("model.getBrowser()="+model.getBrowser()+",browser="+browser);


        if (model.getHost().equals(host) && model.getLoginIp().equals(ip_addr) && model.getBrowser().equals(browser)) {


        } else {
            //System.out.println("No");
            rst.AddError("您已在其他地方登录，系统强制退出！");
            request.getSession().removeAttribute(SESSION.USER);
            return new ModelAndView("redirect:/");
        }


        return new ModelAndView("footer");
    }

    @RequestMapping("/main")
    public ModelAndView main(ModelMap map) {
        String osName = "";
        double cpuRatio = 0;
        double totalMemorySize = 0; //MB
        double usedMemory = 0; //MB
        double freeMemory = 0;
        int totalThread = 0;
        /*try {
            IMonitorService service = new MonitorServiceImpl();
            MonitorInfoBean monitorInfo = service.getMonitorInfoBean();

            osName = monitorInfo.getOsName();
            cpuRatio = monitorInfo.getCpuRatio();
            totalMemorySize = monitorInfo.getTotalMemorySize() / 1024;
            usedMemory = monitorInfo.getUsedMemory() / 1024;
            freeMemory = monitorInfo.getFreeMemory() / 1024;
            totalThread = monitorInfo.getTotalThread();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }*/
        map.addAttribute("osName", osName);
        map.addAttribute("cpuRatio", cpuRatio);
        map.addAttribute("totalMemorySize", totalMemorySize);
        map.addAttribute("usedMemory", usedMemory);
        map.addAttribute("freeMemory", freeMemory);
        map.addAttribute("totalThread", totalThread);

        return new ModelAndView("main");
    }

    @RequestMapping("/count")
    public ModelAndView count(HttpServletRequest request, ModelMap map) {
        String companyId = "";
        String companyName = "";
        AdminUser admin = (AdminUser) request.getSession().getAttribute(SESSION.USER);
        if (admin != null && admin.getRoleId() == CONFIG.COMPANY_ROLEID) {
            companyId = admin.getCompanyId();
            companyName = admin.getCompanyName();
        }
        CountBean countBean = driverService.countAnalysis("", companyId);
        map.addAttribute("countBean", countBean);
        map.addAttribute("companyName", companyName);
        return new ModelAndView("home/count");
    }

    @RequestMapping("/error")
    public ModelAndView error(ModelMap map) {
        return new ModelAndView("error");
    }

    /**
     * 验证码图片
     *
     * @param
     * @return
     */
    @RequestMapping("/authImage")
    public void authImage(@RequestParam(value = "r", required = false) String r, HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        //生成随机字串
        String validCode = VerifyCodeUtil.generateVerifyCode(4);
        //存入会话session
        HttpSession session = request.getSession(true);
        //删除以前的
        session.removeAttribute("validCode");
        session.setAttribute("validCode", validCode.toLowerCase());
        //生成图片
        int w = 100, h = 30;
        VerifyCodeUtil.outputImage(w, h, response.getOutputStream(), validCode);
    }


}
